﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using Microsoft.Build.Utilities;

namespace Genuilder.Extensibility.Targets
{
	public class CrossDomainData : MarshalByRefObject
	{
		public String Assembly
		{
			get;
			set;
		}
		public String Data
		{
			get;
			set;
		}
		public TaskItem[] OutputSources
		{
			get;
			set;
		}
		public void Launch()
		{

		}
	}

	public class AssemblyLoader : IDisposable
	{

		//class CrossDomainDataExtensions
		//{
		//    public static Assembly GetAssembly(CrossDomainData data, AppDomain appDomain)
		//    {
		//        return appDomain.GetAssemblies().First((ass) => ass.FullName.Equals(AssemblyName.GetAssemblyName(data.Path).FullName));
		//    }
		//}



		readonly Dictionary<String, CrossDomainData> _Assemblies = new Dictionary<String, CrossDomainData>();

		readonly AppDomain _SubDomain;
		public AssemblyLoader(string probPath)
		{
			_SubDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString(), null, new AppDomainSetup()
			{
				ApplicationBase = Path.GetDirectoryName(this.GetType().Assembly.Location),
				PrivateBinPath = probPath

			});
		}

		Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
		{
			return AppDomain.CurrentDomain.Load(args.Name);
		}


		#region IDisposable Members

		volatile bool _IsDisposed;
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		~AssemblyLoader()
		{
			Dispose(false);
		}

		private void Dispose(bool disposing)
		{
			if(!_IsDisposed)
			{
				_IsDisposed = true;
				if(disposing)
				{
				}
				AppDomain.Unload(_SubDomain);
			}
		}

		#endregion

		public TaskItem[] HasType(string data, string assembly)
		{
			if(_IsDisposed)
				throw new InvalidOperationException("AssemblyLoader already disposed");
			//if(typeName == null)
			//    throw new ArgumentNullException("typeName");
			var crossData = (CrossDomainData)_SubDomain.CreateInstanceAndUnwrap(this.GetType().Assembly.FullName, typeof(CrossDomainData).FullName);
			return null;
			//return crossData.HasType(assemblyPath, typeName);
		}
	}
}
